package com.kly.sc.api.application.service.trade.impl;

import com.fqgj.base.services.redis.RedisClient;
import com.kly.dto.ProductDiscountConfigDto;
import com.kly.sc.api.application.controller.discount.request.TriggerDiscountRequest;
import com.kly.sc.api.application.controller.discount.response.DiscountInfoResponse;
import com.kly.sc.api.application.controller.discount.response.DiscountResponse;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.trade.ProductDiscountService;
import com.kly.sc.api.application.utils.Result;
import com.kly.enums.ProductCategory;
import com.kly.sc.api.application.utils.RpcUtils;
import com.kly.service.MemberService;
import com.kly.service.ProductDiscountConfigService;
import com.kly.user.constant.RedisKey;
import com.kly.user.dto.UserBackDto;
import com.kly.user.dto.UserPromotionRecordDto;
import com.kly.user.service.UserPromotionRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ProductDiscountServiceImpl implements ProductDiscountService {

    @Resource
    private MemberService memberService;

    @Resource
    private UserPromotionRecordService userPromotionRecordService;

    @Resource
    private ProductDiscountConfigService productDiscountConfigService;

    @Autowired
    RedisClient redisClient;


    @Override
    public Result<Integer> triggerDiscount(TriggerDiscountRequest triggerDiscountRequest) {
        String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();

        //判断是否有过会员
        Boolean haveMemberRecord = RpcUtils.getResult(memberService.haveMemberRecord(triggerDiscountRequest.getUserCode()));
        if (haveMemberRecord) {
            return Result.ok(0);
        }
        //判断是否有促销商品
        ProductDiscountConfigDto productDiscount = productDiscountConfigService.productDiscountCountByPromotionType(1, appCode, null);
        if (productDiscount == null) {
            return Result.ok(0);
        }
        //判断是否有促销记录
        int userPromotionRecordCount = userPromotionRecordService.queryCountByPromotionType(triggerDiscountRequest.getUserCode(), 1);
        if (userPromotionRecordCount > 0) {
            return Result.ok(0);
        }
        //判断用户是否存在正在执行的促销商品
        int userOldPromotionRecordCount = userPromotionRecordService.getUserPromotionCount(triggerDiscountRequest.getUserCode());
        if (userOldPromotionRecordCount > 0) {
            return Result.ok(0);
        }
        UserPromotionRecordDto userPromotionRecordDto = new UserPromotionRecordDto();
        userPromotionRecordDto.setUserCode(triggerDiscountRequest.getUserCode());
        userPromotionRecordDto.setTriggerType(triggerDiscountRequest.getTriggerType());
        userPromotionRecordDto.setPromotionType(1);
        userPromotionRecordDto.setOperationStatus(0);
        userPromotionRecordDto.setBuyType(triggerDiscountRequest.getBuyType() == null ? 2 : triggerDiscountRequest.getBuyType());
        userPromotionRecordService.addUserPromotionRecord(userPromotionRecordDto);
        return Result.ok(1);
    }

    @Override
    public Result<DiscountResponse> getDiscount() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();

        DiscountResponse discountResponse = new DiscountResponse();
        discountResponse.setHavaDiscount(0);
        discountResponse.setHavePop(0);
        discountResponse.setPopOverTime(0);

        //判断是否是会员
        Boolean ifMember = RpcUtils.getResult(memberService.ifMember(userCode));
        if (ifMember) {
            return Result.ok(discountResponse);
        }

        //判断是否有促销记录
        UserPromotionRecordDto userPromotionRecordDto = userPromotionRecordService.getLastByUserCode(userCode);
        if (userPromotionRecordDto != null && userPromotionRecordDto.getOperationStatus() != 2) {
            if (userPromotionRecordDto.getOperationStatus() == 0) {
                //等于0的时候开始促销商品
                ProductDiscountConfigDto productDiscountConfigDto = productDiscountConfigService.productDiscountCountByPromotionType(userPromotionRecordDto.getPromotionType(), appCode, userPromotionRecordDto.getBuyType());
                if (productDiscountConfigDto != null) {
                    if (productDiscountConfigDto.getPopOverTime() > 0) {
                        UserPromotionRecordDto userPromotionRecord = getUserPromotionRecordDto(productDiscountConfigDto, userPromotionRecordDto);
                        userPromotionRecordService.UpdateUserPromotionRecord(userPromotionRecord);
                        addPushMessage(userCode, productDiscountConfigDto.getPopOverTime());
                        return getDiscountResponseResult(discountResponse, productDiscountConfigDto, ProductCategory.USER_DISCOUNT.getCode());
                    }
                }
            } else if (userPromotionRecordDto.getOperationStatus() == 1) {
                if (userPromotionRecordDto.getEndDate().after(new Date())) {
                    long nowDate = new Date().getTime();
                    long endDate = userPromotionRecordDto.getEndDate().getTime();
                    int popOverTime = (int) ((endDate - nowDate) / 1000);
                    discountResponse.setPopOverTime(popOverTime);
                    discountResponse.setHavaDiscount(1);
                    return Result.ok(discountResponse);
                }
            }
        }

        //判断是否需要老用户召回
        UserBackDto userBackDto = userPromotionRecordService.getUserBackByUserCode(userCode);
        if (userBackDto != null && userBackDto.getNoticeStatus() == 0) {
            //根据促销类型，读取促销商品，判断是否商品 有商品 返回商品
            //判断是否有促销商品
            ProductDiscountConfigDto productDiscountConfigDto = productDiscountConfigService.productDiscountCountByPromotionType(userBackDto.getPromotionType(), appCode, userBackDto.getShowType());
            if (productDiscountConfigDto != null) {

                //新增促销记录
                UserPromotionRecordDto userPromotionRecord = new UserPromotionRecordDto();
                userPromotionRecord.setUserCode(userCode);
                userPromotionRecord.setTriggerType(0);
                userPromotionRecord.setPromotionType(userBackDto.getPromotionType());
                userPromotionRecord.setOperationStatus(1);
                userPromotionRecord.setBeginDate(new Date());
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.SECOND, productDiscountConfigDto.getPopOverTime());
                Date endDate = calendar.getTime();
                userPromotionRecord.setEndDate(endDate);
                userPromotionRecord.setBuyType(userBackDto.getShowType());
                userPromotionRecordService.addUserPromotionRecord(userPromotionRecord);
                UserBackDto userBack=new UserBackDto();
                userBack.setId(userBackDto.getId());
                userBack.setNoticeStatus(1);
                userPromotionRecordService.updateUserBack(userBack);
                addPushMessage(userCode, productDiscountConfigDto.getPopOverTime());
                //返回信息
                return getDiscountResponseResult(discountResponse, productDiscountConfigDto, ProductCategory.USER_DISCOUNT.getCode());
            }
        }
        return Result.ok(discountResponse);
    }

    private static UserPromotionRecordDto getUserPromotionRecordDto(ProductDiscountConfigDto productDiscountConfigDto, UserPromotionRecordDto userPromotionRecordDto) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, productDiscountConfigDto.getPopOverTime());
        Date endDate = calendar.getTime();

        //状态修改为在卖 修改开始时间和结束时间
        UserPromotionRecordDto userPromotionRecord = new UserPromotionRecordDto();
        userPromotionRecord.setId(userPromotionRecordDto.getId());
        userPromotionRecord.setOperationStatus(1);
        userPromotionRecord.setBeginDate(new Date());
        userPromotionRecord.setEndDate(endDate);
        return userPromotionRecord;
    }

    /**
     * 返回结果统一处理
     *
     * @param discountResponse
     * @param productDiscountConfigDto
     * @return
     */
    private Result<DiscountResponse> getDiscountResponseResult(DiscountResponse discountResponse, ProductDiscountConfigDto productDiscountConfigDto, Integer productCategory) {
        discountResponse.setHavaDiscount(1);
        discountResponse.setPopOverTime(productDiscountConfigDto.getPopOverTime());
        discountResponse.setHavePop(1);

        DiscountInfoResponse discountInfoResponse = new DiscountInfoResponse();
        discountInfoResponse.setPopTitle(productDiscountConfigDto.getPopTitle());
        discountInfoResponse.setPopContent(productDiscountConfigDto.getPopContent());
        discountInfoResponse.setPopTag(productDiscountConfigDto.getPopTag());
        discountInfoResponse.setPromotionPrice(productDiscountConfigDto.getPromotionPrice());
        discountInfoResponse.setPromotionDelPrice(productDiscountConfigDto.getPromotionDelPrice());
        discountInfoResponse.setPromotionNote(productDiscountConfigDto.getPromotionNote());
        discountInfoResponse.setPopButton(productDiscountConfigDto.getPopButton());
        discountInfoResponse.setPopButtonTitle(productDiscountConfigDto.getPopButtonTitle());
        discountInfoResponse.setPopButtonContent(productDiscountConfigDto.getPopButtonContent());
        discountInfoResponse.setProductCode(productDiscountConfigDto.getProductCode());
        discountInfoResponse.setProductCategory(productCategory);
        discountResponse.setDiscountInfoResponse(discountInfoResponse);
        return Result.ok(discountResponse);
    }

    /**
     * 消息推送
     *
     * @param userCode
     * @param popOverTime
     */
    private void addPushMessage(String userCode, Integer popOverTime) {
        try {
            if (popOverTime > 180) {
                int noticeTime = popOverTime - 180;
                long delayedTime = System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(noticeTime, TimeUnit.SECONDS);
                redisClient.zAdd(RedisKey.DISCOUNT_MESSAGE_USER_LIST, delayedTime, userCode);
            }
            if (popOverTime > 120) {
                int noticeTime = popOverTime - 120;
                long delayedTime = System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(noticeTime, TimeUnit.SECONDS);
                redisClient.zAdd(RedisKey.DISCOUNT_PUSH_USER_LIST, delayedTime, userCode);
            }
        } catch (Exception e) {
            log.error("DISCOUNT_MESSAGE_USER_LIST error: {}", e.getMessage());
        }
    }

}
